package com.monster.security.filter;

import com.monster.exception.impl.MonsterNoTackException;
import com.monster.json.JsonUtils;
import com.monster.security.common.MonsterSecurityExceptionEnum;
import com.monster.security.data.utils.RsaUtils;
import com.monster.starter.core.common.config.http.HttpRequestConfig;
import com.monster.starter.security.common.SecurityExceptionEnum;
import com.monster.starter.security.common.entity.SysRsaInfo;
import com.monster.starter.security.service.TransmissionCipherService;
import com.monster.utils.StringUtils;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.SneakyThrows;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.stereotype.Component;

import java.nio.charset.StandardCharsets;
import java.util.Map;

/**
 * 修改获取用户名的方式
 *
 * @author kuangxz
 */
@Component
public class MonsterUsernamePasswordAuthenticationFilter extends UsernamePasswordAuthenticationFilter {
    /**
     * 请求的统一配置
     */
    @Autowired
    private HttpRequestConfig requestConfig;
    /**
     * 传输密钥管理
     */
    @Autowired
    private TransmissionCipherService cipherService;
    @SneakyThrows
    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) {
        UsernamePasswordAuthenticationToken authRequest = null;

        if (request.getMethod().equals(HttpMethod.POST.toString())) {
            // 解析密码
            String user = IOUtils.toString(request.getInputStream(), StandardCharsets.UTF_8);
            if (StringUtils.isEmpty(user)) {
                throw new MonsterNoTackException(MonsterSecurityExceptionEnum.USER_LOGIN,"没有收到相应的请求数据");
            }
            SysRsaInfo info = cipherService.get(request.getHeader(requestConfig.getCipherName()));
            if (info == null) {
                throw new MonsterNoTackException(MonsterSecurityExceptionEnum.USER_LOGIN,"根据请求头信息没有获取到相关的密钥信息");
            }
            // 获取内容
            Map<String, String> userInfo = JsonUtils.readValue(user, Map.class);
            String username = userInfo.get(this.getUsernameParameter());
            String password = userInfo.get(this.getPasswordParameter());

            // 空判断
            if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password)) {
                throw new MonsterNoTackException(MonsterSecurityExceptionEnum.USER_LOGIN,"用户名和密码为空");
            }

            // 解密key
            password = RsaUtils.decryptByPrivate(info.getSPrivateCipher(), password);
            if (password == null) {
                throw new MonsterNoTackException(SecurityExceptionEnum.DECRYPT_ERROR, "无法解密前端传输的密码");
            }
            authRequest = new UsernamePasswordAuthenticationToken(username, password);
            setDetails(request, authRequest);
        }

        return this.getAuthenticationManager().authenticate(authRequest);
    }

    @Lazy
    @Autowired
    @Override
    public void setAuthenticationManager(AuthenticationManager authenticationManager) {
        super.setAuthenticationManager(authenticationManager);
    }
}
